<?php

namespace tmcore\services\upload\driver;

use tmcore\exceptions\UploadException;
use tmcore\services\upload\BaseUpload;
use Qiniu\Auth;
use Qiniu\Storage\UploadManager;
use Qiniu\Storage\BucketManager;

/**
 * 七牛云存储引擎
 */
class Qiniu extends BaseUpload
{
    private $qiniuClient;

    private $qiniuToken;

    private $qiniuAuth;

    /**
     * 初始化
     * @param array $config
     * @return mixed|void
     */
    protected function initialize(array $config)
    {
        parent::initialize($config);

        // 构建鉴权对象
        $this->qiniuAuth = new Auth($this->fileConfig['accessKey'], $this->fileConfig['secretKey']);

        // 要上传的空间
        $this->qiniuToken = $this->qiniuAuth->uploadToken($this->fileConfig['bucket']);

        // 初始化 UploadManager 对象并进行文件的上传
        $this->qiniuClient = new UploadManager();
    }


    /**
     * 上传文件
     * @param string $name 文件对象 name
     * @param array $rule 上传规则 ['fileSize' => 0, 'fileExt' => 'jpg', 'image' => '200,200,jpg']
     * @param string $file_type 文件类型
     * @return array
     * @throws UploadException
     */
    public function upload(string $name, array $rule, string $file_type = 'image') {

        try {
            //接受文件
            $file = $this->getFileInfo($name);
            //验证文件
            $this->validate($name, $rule);

            $file_path = $file->getFileInfo()['tmp_name'];

            //上传文件
            list($result, $error) = $this->qiniuClient->putFile($this->qiniuToken, $this->getSavePath($file_type) . '/' . $this->fileInfo['fileName'], $file_path);
            if($error !== null) throw new \Exception($error->message());

            $this->fileInfo['url'] = $result['key'];

            return $this->fileInfo;

        } catch (UploadException $e) {
            throw new UploadException($e->getMessage());
        } catch (\Exception $e) {
            throw new UploadException($e->getMessage());
        }
    }


    /**
     * 远程文件下载存储
     * @param string $url 文件路径
     * @param string $file_type 文件类型
     * @return array
     * @throws UploadException
     */
    public function fetch(string $url, string $file_type = 'image') {

        try {

            $ext = $this->getFileExt($url);

            $file_name = $this->buildSaveName($ext);

            if (substr($url, 0, 1) !== '/' || strstr($url, 'http://') || strstr($url, 'https://')) {
                $bucketManager = new BucketManager($this->qiniuAuth);
                list($result, $error) = $bucketManager->fetch($url, $this->fileConfig['bucket'], $this->getSavePath($file_type) . '/' . $file_name);
            } else {
                list($result, $error) = $this->qiniuClient->putFile($this->qiniuToken, $this->getSavePath($file_type) . '/' . $file_name, $url);
            }

            if($error !== null) throw new \Exception($error->message());

            $this->fileInfo['url'] = $result['key'];;

            return [
                'ext'          => $ext,
                'size'         => strlen(file_get_contents($url)),
                'md5'          => '',
                'sha1'         => '',
                'originalName' => preg_replace('/^.+[\\\\\\/]/', '', $url),
                'fileName'     => $file_name,
                'url'          => $result['key']
            ];

        } catch (\Exception $e) {
            throw new UploadException($e->getMessage());
        }
    }


    /**
     * 批量上传文件
     * @param string $name 文件对象 name
     * @param array $rule 上传规则 ['fileSize' => 0, 'fileExt' => 'jpg', 'image' => '200,200,jpg']
     * @param string $file_type 文件类型 image-图片 file-文件
     * @return bool|array
     * @throws UploadException
     */
    public function batchUpload(string $name, array $rule, string $file_type = 'image') {

        try {
            //接受文件
            $files = $this->getFileInfo($name, true);
            //循环检验
            foreach($files as $file) {
                $this->validate($name, $rule, $file);
            }

            foreach($files as $key => $file) {
                //上传文件
                list($result, $error) = $this->qiniuClient->putFile($this->qiniuToken, $this->getSavePath($file_type) . '/' . $this->fileInfo['fileName'], $file['file']->getRealPath());
                if(!$error !== null) throw new \Exception($error->message());
                $this->fileInfo[$key]['url'] = $result['key'];
            }

            return $this->fileInfo;

        } catch (UploadException $e) {
            throw new UploadException($e->getMessage());
        } catch (\Exception $e) {
            throw new UploadException($e->getMessage());
        }
    }


    /**
     *  删除文件
     * @param $fileName
     * @return bool|mixed
     * @throws UploadException
     */
    public function delete($fileName)
    {
        // 初始化 UploadManager 对象并进行文件的上传
        $bucketMgr = new BucketManager($this->qiniuAuth);

        try {
            list(, $error) = $bucketMgr->delete($this->fileConfig['bucket'], $fileName);
            if ($error !== null) throw new \Exception($error->message());
            return true;
        } catch (\Exception $e) {
            throw new UploadException($e->getMessage());
        }
    }
}
